﻿#include "pch.h"

#include <format>
#include <numeric>
#include <random>
#include <span>
#include <unordered_map>
#include <windows.h>

#include "AA.h"
using std::cout;
using std::endl;

void AppendName(std::string& s1, const std::string& s2) {
	s1 = s1 + s2;
}

TEST(STD, string) {
	auto name = std::string("lion");
	AppendName(name, std::string("sd"));
	std::cout << name << std::endl;
	EXPECT_TRUE(name == "lionsd");
}

TEST(STD, strMove) {
	std::string hw = "hhh www";
	std::string hw1 = move(hw);
	std::cout << "origin: " << hw << std::endl;
	std::cout << "moved: " << hw1 << std::endl;
}

void createArr(int x) {
	std::unique_ptr<int[]> arr(new int[x]);
	for (int i = 0; i < x; ++i) {
		const auto tmp = arr[i];
		cout << tmp << endl;
	}
}

TEST(STD, arr) {
	createArr(3);
}


TEST(STD, vector) {
	auto p = std::pair<float, float>(0.0, 0.0);
	auto f = p.first;
	auto s = p.second;

	auto vp = std::vector(1, std::pair<float, float>(0.0, 0.0));
}


TEST(STD, vector_insert) {
	std::vector<int> vector1;
	std::vector<int> vector2 = {4, 5, 6};
	std::vector<int> vector3 = {4, 5, 6};

	vector1.insert(vector1.end(), vector2.begin(), vector2.end());
	vector1.insert(vector1.end(), vector3.begin(), vector3.end());

	for (int num : vector1) {
		std::cout << num << " ";
	}
}

TEST(STD, vector_end) {
	std::vector<int> vector = {4, 5, 6};
	cout << *(--vector.end()) << endl;
}


TEST(STD, aabb) {
	xxx::AA aa;
	aa.Hw();
}


/**
 * \brief  Simplify floating - point numbers by reducing accuracy
 * \param fs
 */
std::vector<float> SimplifyFloats(std::vector<float> fs, const float& jd = 1E-2) {
	std::vector<float> res;

	const float precision = jd == 0 ? 1 : jd;
	const int cd = static_cast<int>(1.0 / precision);
	for (auto re : fs) {
		auto find = std::find_if(res.begin(), res.end(), [&](float item) {
			return static_cast<int>(item * cd) == static_cast<int>(re * cd);
		});
		if (find == res.end()) {
			res.push_back(re);
		}
	}
	return res;
}


TEST(STD, jd) {
	constexpr float jd = 1E-2f;
	std::vector<float> arr = {1.322342f, 2.54123f, 1.332423f, 2.54545f, 3.4343f, 1.33343454f};
	arr = SimplifyFloats(arr, jd);

	for (auto item : arr) {
		cout << item << "|";
	}
}

TEST(format, f1) {
	int a = 11;
	for (int i = 0; i < a; ++i) {
		std::string str = std::format("asd {}", i);
		cout << str << endl;;
	}
}

TEST(map, m1) {
	std::unordered_map<int, char> example = {{1, 'a'}, {2, 'b'}};

	for (int x : {2, 5}) {
		if (example.contains(x)) {
			std::cout << x << ": Found\n";
		}
		else {
			std::cout << x << ": Not found\n";
		}
	}
}

struct FObj {
	int i, j;
};

TEST(find, f1) {
	std::vector<FObj> fv = {FObj(1, 2), FObj(3, 4), FObj(4, 5), FObj(9, 3)};
	int tar = 3;
	auto it = std::ranges::find_if(fv, [tar](const FObj& f) {
		return f.i == tar;
	});
	FObj found = fv.front();
	if (it != fv.end()) {
		found = *it;
	}
	cout << found.i << endl;
	cout << found.j << endl;
}

TEST(PInt, p1) {
	const int i = 1;
	const int* x = &i;
	const int j = 2;
	x = &j;
	const int& refI = i;
	x = &refI;
	cout << *x << endl;
}

int sum(int num, ...) {
	int sum = 0;
	va_list argPtr;
	va_start(argPtr, num);
	for (int i = 0; i < num; ++i) {
		sum += va_arg(argPtr, int);
	}
	va_end(argPtr);
	return sum;
}

TEST(Sum, s1) {
	cout << "sum(1,5):" << sum(1, 5) << endl;
	cout << "sum(3,1,2,3):" << sum(3, 1, 2, 3) << endl;
	cout << "sum(3,1,2,3,4):" << sum(3, 1, 2, 3, 4) << endl;
	cout << "sum(3,1,2,3.4):" << sum(3, 1, 2, 3.4) << endl;
}

template <class... Args>
auto sum1(Args... args) {
	return (... + args);
}

TEST(Sum, s2) {
	cout << "sum(1,5):" << sum1(1, 5) << endl;
	cout << "sum(3,1,2,3):" << sum1(3, 1, 2, 3) << endl;
	cout << "sum(3,1,2,3,4):" << sum1(3, 1, 2, 3, 4) << endl;
	cout << "sum(3,1,2,3.4):" << sum1(3, 1, 2, 3.4) << endl;
}


struct MyObject {
	int category;
	std::string name;
};

TEST(map, m2) {
	std::vector<MyObject> objects = {
		{1, "Object1"},
		{2, "Object2"},
		{1, "Object3"},
		{3, "Object4"},
		{2, "Object5"},
	};

	std::unordered_map<int, std::vector<MyObject>> categoryMap;

	// 遍历 vector 并将元素分类到 unordered_map 中
	for (const MyObject& obj : objects) {
		categoryMap[obj.category].push_back(obj);
	}
	bool res = categoryMap.contains(4);
	cout << "contain:" << res << "\n";
	// 打印分类结果
	for (const auto& entry : categoryMap) {
		int category = entry.first;
		const std::vector<MyObject>& categoryObjects = entry.second;
		std::cout << "Category " << category << ":" << std::endl;
		for (const MyObject& obj : categoryObjects) {
			std::cout << "  " << obj.name << std::endl;
		}
	}
}


TEST(map, m_int_int) {
	// 创建一个 std::map，其中键是 std::pair<int, int>，值是字符串
	std::map<std::pair<int, int>, std::string> myMap;

	// 插入一对键值对
	myMap[std::make_pair(1, 2)] = "493GXl";
	myMap[std::make_pair(3, 4)] = "5k3zW";
	myMap[std::make_pair(852, 229)] = "3EI5jx";

	// 访问和打印值
	std::pair<int, int> key = std::make_pair(324, 3);
	cout << myMap.contains(key) << endl;;
	std::cout << "Value for key (1, 2): " << myMap[key] << std::endl;
}

#include <iostream>
#include <map>

struct MyKey {
	int x;
	int y;

	bool operator<(const MyKey& other) const {
		// 定义比较操作符
		if (x == other.x) {
			return y < other.y;
		}
		return x < other.x;
	}
};

TEST(map, m4) {
	std::map<MyKey, std::string> myMap;

	// 插入键值对
	myMap[{1, 2}] = "jg9g8";
	myMap[{3, 4}] = "H5yNu48";

	// 访问值
	MyKey key = {1, 2};
	std::cout << "Value for key (1, 2): " << myMap[key] << std::endl;
}

TEST(Span, s1) {
	std::vector<int> vec = {1, 2, 3, 4, 5};

	// 创建一个 span，包括整个 vector
	std::span<int> mySpan(vec);

	// 使用 span 迭代元素
	for (int element : mySpan) {
		std::cout << element << " ";
	}
	std::cout << std::endl;

	// 修改 span 中的元素
	mySpan[2] = 42;

	// 原 vector 也被修改了
	for (int element : vec) {
		std::cout << element << " ";
	}
	std::cout << std::endl;
}


// 接受一个字符串的函数，使用移动语义
void processString(std::string&& str) {
	// 在这里，str 是一个右值引用，可以将其移动到新的对象
	std::string copy = std::move(str); // 使用 std::move 移动字符串

	// 现在，str 不再包含有效的字符串，它被移动到了 copy 中
	std::cout << "Copy: " << copy << std::endl;
	std::cout << "Original (empty): " << str << std::endl;
}

TEST(stdMOVE, sm1) {
	std::string myString = "Hello, World!";

	// 调用函数并传递右值引用
	processString(std::move(myString));

	// 此时，myString 不再包含有效的字符串，因为它被移动到了函数中
	std::cout << "Main (empty): " << myString << std::endl;
}

TEST(re, r1) {
	int value = 10; // 初始化一个变量

	// 后续根据条件修改变量
	int& ref = value; // 引用原始变量
	if (true) {
		ref = 20; // 修改原始变量的值
	}
	else {
		ref = 30; // 修改原始变量的值
	}

	// 现在 value 的值已经被修改
	std::cout << "value: " << value << std::endl;
}

TEST(point, p1) {
	int value = 34; // 初始化一个变量

	// 后续根据条件修改变量
	int* ptr = &value; // 指向原始变量的指针
	if (true) {
		*ptr = 80; // 修改原始变量的值
	}
	else {
		*ptr = 30; // 修改原始变量的值
	}

	// 现在 value 的值已经被修改
	std::cout << "value: " << value << std::endl;
}

struct VObject {
	std::string id;
	int count;

	VObject operator+(const VObject& other) const {
		return VObject{id, count + other.count};
	}
};

void ChangeV(std::unique_ptr<VObject>& v, const std::vector<VObject>& vs) {}

TEST(Vector, v1) {
	std::vector<VObject> vs = {{"O05f7Xwi", 384}, {"078VKSTG", 960}, {"11h0", 432}};
	for (auto& v : vs) {
		cout << v.id << "," << v.count << endl;
	}
	for (auto& v : vs) {
		std::unique_ptr<VObject> v_ptr = std::make_unique<VObject>(v);
		ChangeV(v_ptr, vs);
		v_ptr->count = v_ptr->count - 1;
	}
	cout << "after --------------------" << endl;
	for (auto& v : vs) {
		cout << v.id << "," << v.count << endl;
	}
}

const VObject* get_ptr(const std::vector<VObject>& vs) {
	return &vs[0];
}

TEST(pointer, p1) {
	// 创建一个const vector
	std::vector<VObject> vs = {{"O05f7Xwi", 384}, {"078VKSTG", 960}, {"11h0", 432}};
	get_ptr(vs);
}

TEST(Acc, a1) {}


TEST(map_transform, m1) {
	// 原始向量
	std::vector<int> originalVector = {1, 2, 3, 4, 5};

	// 目标数组
	std::vector<int> transformedArray(originalVector.size());

	// 使用 std::transform 将原始向量转换为目标数组
	std::transform(originalVector.begin(), originalVector.end(), transformedArray.begin(),
	               [](int element) { return element * 2; });

	// 输出转换后的数组
	std::cout << "Transformed Array: ";
	for (int element : transformedArray) {
		std::cout << element << " ";
	}
	std::cout << std::endl;
}

std::string getMapValue(std::unordered_map<int, std::string> myMap, int key) {
	return myMap[key];
}

TEST(unordermap, map2) {
	std::unordered_map<int, std::string> myMap;

	// 插入键值对
	myMap[1] = "noe";
	myMap[2] = "s";
	myMap[3] = "asd";

	// 使用[]运算符获取元素
	std::cout << "Value associated with key 'two': " << myMap[1] << std::endl;

	// 如果键不存在，[]运算符会插入新元素
	std::cout << "Value associated with key 'four': " << myMap[4] << std::endl;
}

double random_real() {
	// 创建一个 `std::mt19937` 实例
	static std::random_device rd;
static 	std::mt19937 gen(rd());
static std::uniform_real_distribution<double> dist(0.0, 1.00);//设

	// 生成一个 0 到 1 之间的浮点数
	return dist(gen);

	

}
TEST(Random ,r1) {
	for (int i = 0; i < 100; ++i) {
		std::cout << random_real ()<< std::endl;

	}

}

int random_int(int i,int j) {
	// 创建一个 `std::mt19937` 实例
	static std::random_device rd;
	static 	std::mt19937 gen(rd());
	 std::uniform_int_distribution<> dist(i, j);//设

	// 生成一个 0 到 1 之间的浮点数
	return dist(gen);
}

TEST(Random, r2) {
	

	// 打印生成的随机数
	for (int i = 0; i < 100; ++i) {
		std::cout << random_int(0, i) << std::endl;
	}
;

}
